#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void PrintPending(const sigset_t &pending)
{
    // 位图打印出来，从左到右是从小到大
    // 约定：pending中存在为1，不存在为0
    for (int signo = 1; signo <= 31; signo++)
    {
        if (sigismember(&pending, signo))
            std::cout << "1";
        else
            std::cout << "0";
    }
    std::cout << std::endl;
}
int main()
{
    std::cout << "pid: " << getpid() << std::endl;
    // 1. 屏蔽2号信号
    sigset_t set, oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set, 2);
    sigprocmask(SIG_BLOCK, &set, &oset);

    // 2. 不断获取当前进程的pending表
    int cnt = 0;
    sigset_t pending;
    while (true)
    {
        if(0 == sigpending(&pending)) PrintPending(pending);
        sleep(1);

        cnt++;
        if(10 == cnt)
        {
            std::cout << "解除对2号信号的屏蔽，2号信号准备递达" << std::endl;
            sigprocmask(SIG_SETMASK, &oset, nullptr);
        }
    }
    return 0;
}

// 信号集操作函数演示 -- 屏蔽2号信号
// int main()
// {
//     std::cout << "pid: " << getpid() << std::endl;
//     sigset_t block, oblock;

//     sigemptyset(&block);
//     sigemptyset(&oblock);

//     sigaddset(&block, 2); // 这只是设置2号信号，还没有对block表中修改

//     sigprocmask(SIG_BLOCK, &block, &oblock); // 屏蔽操作
//     while(true)
//     {
//         std::cout << "running ..." << std::endl;
//         sleep(1);
//     }

//     return 0;
// }

// 递达的三种情况：默认、忽略、自定义
// void handler(int signo)
// {
//     std::cout << "signal number: " << signo << std::endl;
// }
// int main()
// {
//     signal(2, handler);
//     std::cout << "running ..." << std::endl;
//     sleep(2);

//     signal(2, SIG_IGN); // 忽略
//     std::cout << "running ..." << std::endl;
//     std::cout << "running ..." << std::endl;
//     std::cout << "running ..." << std::endl;
//     sleep(3);

//     signal(2, SIG_DFL); // 默认
//     std::cout << "running ..." << std::endl;
//     std::cout << "running ..." << std::endl;
//     std::cout << "running ..." << std::endl;
//     sleep(1);

//     return 0;
// }
